from tkinter import *   #导入相关模块，定义Calendar类
import time
class Calendar:
    def __init__(self):
        self.vYear = StringVar()
        self.vMonth = StringVar()
        self.vDay = StringVar()

    def leap_year(self,year):
        # 判断是否为闰年
        if ((year % 4 == 0) and (year % 100 != 0)) or (year % 400 == 0):
            return True
        else:
            return False

    def year_days(self,year,month):
        # 给定年月返回月份的天数
        if month in (1,3,5,7,8,10,12):
            return 31
        elif month in (4,6,9,11):
            return 30
        else:
            if self.leap_year(year) == True:
                return 29
            else:
                return 28

    def get_total_days(self,year,month):
        total_days = 0
        for m in range(1800,year):
            if self.leap_year(m) == True:
                total_days += 366
            else:
                total_days += 365
        for i in range(1,month):
            total_days += self.year_days(year,i)
        return total_days

    def calcFirstDayOfMonth(self,year,month):
        return (self.get_total_days(year,month)+3)%7

    def createMonth(self,master):
        for i in range(6):
            for j in range(7):
                Label(master,text = '').grid(row = i + 2,column = j)
    def updateDate(self):
        year = int(self.vYear.get())
        month = int(self.vMonth.get())
        day = int(self.vDay.get())
        fd = self.calcFirstDayOfMonth(year,month)
        for i in range(6):
            for j in range(7):
                root.grid_slaves(i +2,j)[0]['text'] = ''
        days = self.year_days(year,month)
        for i in range(1, days + 1):
            root.grid_slaves((i + fd - 1)//7 + 2,(i + fd - 1)%7)[0]['text'] = str(i)

    def drawHeader(self,master):
        #得到当前日期，设置为默认值
        now = time.localtime(time.time())
        col_idx = 0
        #创建年组件
        self.vYear = StringVar()
        self.vYear.set(now[0])
        Label(master,text = '年').grid(row = 0,column = col_idx);col_idx += 1
        omYear = OptionMenu(master,self.vYear,*tuple(range(2005,2022)))
        omYear.grid(row = 0,column = col_idx);col_idx += 1

        #创建月份组件
        self.vMonth.set(now[1])
        Label(master,text = '月').grid(row = 0,column = col_idx);col_idx += 1
        omDay = OptionMenu(master, self.vMonth, *tuple(range(1,13)))
        omDay.grid(row=0, column=col_idx);col_idx += 1

        # 创建日份组件
        self.vDay.set(now[2])
        Label(master, text='日').grid(row=0, column=col_idx);col_idx += 1
        omDay = OptionMenu(master, self.vDay, *tuple(range(1, 32)))
        omDay.grid(row=0, column=col_idx);col_idx += 1

        #创建‘更新日历’按钮
        btupdate = Button(master,text = '更新日历',command = self.updateDate)
        btupdate.grid(row = 0,column = col_idx);col_idx += 1
        weeks = ['周日','周一','周二','周三','周四','周五','周六']
        for week in weeks:
            Label(master,text = week).grid(row = 1,column = weeks.index(week))

root = Tk()
root.title("万年历")
AppCal = Calendar()
AppCal.drawHeader(root)
AppCal.createMonth(root)
AppCal.updateDate()
root.mainloop()